#include"thread.h"
#include"log.h"

static qtch::Logger::ptr logger = QTCH_LOG_NAME("system");

thread_local qtch::Thread * t_thread = nullptr;
thread_local std::string t_thread_name = "UNKNOW";

namespace qtch{

    Thread::Thread(std::function<void()> cb,std::string name)
        :m_cb(cb),m_name(name){
        if(m_name.empty()){
            m_name = "UNKNOW";
        }
        int rt = pthread_create(&m_thread,NULL,run,this);
        if(rt){
            QTCH_LOG_ERROR(logger) << "pthread_create thread fail, rt=" << rt
            << " name=" << name;
            throw std::logic_error("pthread_create error");
        }
        m_sem.wait();
    }

    void* Thread::run(void* arg){
        Thread* thread = (Thread*)arg;
        thread->m_id = GetThreadId();
        t_thread = thread;
        t_thread_name = thread->m_name;
        pthread_setname_np(thread->m_thread,thread->m_name.c_str());

        QTCH_LOG_DEBUG(logger) << "start new thread"
                << " ThreadName:"<<  t_thread_name
                << " ThreadId:" << thread->m_id;

        thread->m_sem.notify();
        thread->m_cb();
        t_thread = nullptr;
        return 0;
    }

    void Thread::join(){
        pthread_join(m_thread,NULL);
    }

    const std::string Thread::GetThreadName(){ 
        return t_thread_name;
    }
    
    Thread * Thread::GetThis(){
        return t_thread;
    }

    void Thread::SetName(const std::string& name){
        if(name.empty()){
            return;
        }
        if(t_thread){
            t_thread->m_name = name;
        }
        t_thread_name = name;
    }

}